#include <iostream>
#include <limits>

#include <QString>
#include <QtTest>

#include <math/MSc_Matrix3x3.h>

////////////////////////////////////////////////////////////////////////////////

class MSc_Matrix3x3Test : public QObject
{
    Q_OBJECT

public:

    MSc_Matrix3x3Test();

private Q_SLOTS:

    void testConstructor();

    void testGetTransposed();

    void testGetFrom();

    void testGetRotationMatrix();

    void testOperatorAssign();
    void testOperatorAddition();
    void testOperatorSubstraction();
    void testOperatorMultiplication();
    void testOperatorDivision();
    void testOperatorUnaryAddition();
    void testOperatorUnarySubstraction();
    void testOperatorUnaryMultiplication();
    void testOperatorUnaryDivision();
};

////////////////////////////////////////////////////////////////////////////////

MSc_Matrix3x3Test::MSc_Matrix3x3Test() {}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testConstructor()
{
    MSc_Matrix3x3 mtrx_1;

    QVERIFY( fabs( mtrx_1(0,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) ) < 10.0e-9 );

    mtrx_1(0,0) = 1.0;
    mtrx_1(0,1) = 2.0;
    mtrx_1(0,2) = 3.0;
    mtrx_1(1,0) = 4.0;
    mtrx_1(1,1) = 5.0;
    mtrx_1(1,2) = 6.0;
    mtrx_1(2,0) = 7.0;
    mtrx_1(2,1) = 8.0;
    mtrx_1(2,2) = 9.0;

    MSc_Matrix3x3 mtrx_2( mtrx_1 );

    QVERIFY( fabs( mtrx_2(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,1) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,2) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,0) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,1) - 5.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,2) - 6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,0) - 7.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,1) - 8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,2) - 9.0 ) < 10.0e-9 );

    MSc_Matrix3x3 mtrx_3( &mtrx_1 );

    QVERIFY( fabs( mtrx_3(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,1) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,2) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,0) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,1) - 5.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,2) - 6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,0) - 7.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,1) - 8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,2) - 9.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testGetTransposed()
{
    MSc_Matrix3x3 mtrx_1;

    // 1, 2, 3
    // 4, 5, 6
    // 7, 8, 9

    mtrx_1(0,0) = 1.0;
    mtrx_1(0,1) = 2.0;
    mtrx_1(0,2) = 3.0;
    mtrx_1(1,0) = 4.0;
    mtrx_1(1,1) = 5.0;
    mtrx_1(1,2) = 6.0;
    mtrx_1(2,0) = 7.0;
    mtrx_1(2,1) = 8.0;
    mtrx_1(2,2) = 9.0;

    MSc_Matrix3x3 mtrx_2 = mtrx_1.getTransposed();

    // 1, 4, 7
    // 2, 5, 8
    // 3, 6, 9

    QVERIFY( fabs( mtrx_2(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,1) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,2) - 7.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,0) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,1) - 5.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,2) - 8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,0) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,1) - 6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,2) - 9.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testGetFrom()
{
    MSc_Matrix3x3 mtrx_1;

    double array[ 9 ] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };

    mtrx_1 = MSc_Matrix3x3::getFrom( array );

    QVERIFY( fabs( mtrx_1.getItem(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(0,1) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(0,2) - 3.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1.getItem(1,0) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(1,1) - 5.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(1,2) - 6.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1.getItem(2,0) - 7.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(2,1) - 8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1.getItem(2,2) - 9.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testGetRotationMatrix()
{
    MSc_Matrix3x3 mtrx_1;

    double phi = 0.0;
    double tht = 0.0;
    double psi = 0.0;

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( phi, tht, psi );

    QVERIFY( fabs( mtrx_1(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 1.0 ) < 10.0e-9 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Angles3::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 1.0 ) < 10.0e-9 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Quaternion::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.0 ) < 10.0e-9 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 0.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 1.0 ) < 10.0e-9 );

    phi = M_PI / 2.0;
    tht = M_PI / 3.0;
    psi = M_PI / 4.0;

//    0.353553,0.353553,-0.866025
//    0.612372,0.612372,0.5
//    0.707107,-0.707107,3.06152e-17

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( phi, tht, psi );

    QVERIFY( fabs( mtrx_1(0,0) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.866025 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.000000 ) < 10.0e-5 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Angles3::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.866025 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.000000 ) < 10.0e-5 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Quaternion::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.353553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.866025 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.612372 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.707107 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.000000 ) < 10.0e-5 );

    phi = M_PI / 4.0;
    tht = M_PI / 4.0;
    psi = M_PI / 4.0;

//    0.5,0.5,-0.707107
//    -0.146447,0.853553,0.5
//    0.853553,-0.146447,0.5

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( phi, tht, psi );

    QVERIFY( fabs( mtrx_1(0,0) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.707107 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.500000 ) < 10.0e-5 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Angles3::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.707107 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.500000 ) < 10.0e-5 );

    mtrx_1 = MSc_Matrix3x3::getRotationMatrix( MSc_Quaternion::getFrom( phi, tht, psi ) );

    QVERIFY( fabs( mtrx_1(0,0) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,1) - 0.500000 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(0,2) + 0.707107 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(1,0) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,1) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(1,2) - 0.500000 ) < 10.0e-5 );

    QVERIFY( fabs( mtrx_1(2,0) - 0.853553 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,1) + 0.146447 ) < 10.0e-5 );
    QVERIFY( fabs( mtrx_1(2,2) - 0.500000 ) < 10.0e-5 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorAssign()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;
    MSc_Matrix3x3 mtrx_3;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2 = mtrx_1;

    QVERIFY( fabs( mtrx_2(0,0) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,1) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,2) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,0) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,1) - 5.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,2) - 6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,0) - 7.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,1) - 8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,2) - 9.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorAddition()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;
    MSc_Matrix3x3 mtrx_3;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2(0,0) =  1.0;
    mtrx_2(0,1) =  2.0;
    mtrx_2(0,2) =  3.0;
    mtrx_2(1,0) =  4.0;
    mtrx_2(1,1) =  5.0;
    mtrx_2(1,2) =  6.0;
    mtrx_2(2,0) =  7.0;
    mtrx_2(2,1) =  8.0;
    mtrx_2(2,2) =  9.0;

    mtrx_3 = mtrx_1 + mtrx_2;

    QVERIFY( fabs( mtrx_3(0,0) -  2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,1) -  4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,2) -  6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,0) -  8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,1) - 10.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,2) - 12.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,0) - 14.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,1) - 16.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,2) - 18.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorSubstraction()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;
    MSc_Matrix3x3 mtrx_3;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2(0,0) =  1.0;
    mtrx_2(0,1) =  2.0;
    mtrx_2(0,2) =  3.0;
    mtrx_2(1,0) =  4.0;
    mtrx_2(1,1) =  5.0;
    mtrx_2(1,2) =  6.0;
    mtrx_2(2,0) =  7.0;
    mtrx_2(2,1) =  8.0;
    mtrx_2(2,2) =  9.0;

    mtrx_3 = mtrx_1 - mtrx_2;

    QVERIFY( fabs( mtrx_3(0,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,2) ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorMultiplication()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;
    MSc_Matrix3x3 mtrx_3;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2(0,0) =  9.0;
    mtrx_2(0,1) =  8.0;
    mtrx_2(0,2) =  7.0;
    mtrx_2(1,0) =  6.0;
    mtrx_2(1,1) =  5.0;
    mtrx_2(1,2) =  4.0;
    mtrx_2(2,0) =  3.0;
    mtrx_2(2,1) =  2.0;
    mtrx_2(2,2) =  1.0;

    mtrx_3 = 2.0 * mtrx_1;

    QVERIFY( fabs( mtrx_3(0,0) -  2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,1) -  4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,2) -  6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,0) -  8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,1) - 10.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,2) - 12.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,0) - 14.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,1) - 16.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,2) - 18.0 ) < 10.0e-9 );

    mtrx_3 = mtrx_1 * mtrx_2;

    QVERIFY( fabs( mtrx_3(0,0) -  30.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,1) -  24.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(0,2) -  18.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,0) -  84.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,1) -  69.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(1,2) -  54.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,0) - 138.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,1) - 114.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_3(2,2) -  90.0 ) < 10.0e-9 );

    MSc_Vector3 vect_1;
    MSc_Vector3 vect_2;

    vect_1(0) = 1.0;
    vect_1(1) = 2.0;
    vect_1(2) = 3.0;

    vect_2 = mtrx_1 * vect_1;

    QVERIFY( fabs( vect_2(0) - 14.0 ) < 10.0e-9 );
    QVERIFY( fabs( vect_2(1) - 32.0 ) < 10.0e-9 );
    QVERIFY( fabs( vect_2(2) - 50.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorDivision()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2 = mtrx_1 / 2.0;

    QVERIFY( fabs( mtrx_2(0,0) - 0.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,1) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(0,2) - 1.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,0) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,1) - 2.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(1,2) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,0) - 3.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,1) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_2(2,2) - 4.5 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorUnaryAddition()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2(0,0) =  1.0;
    mtrx_2(0,1) =  2.0;
    mtrx_2(0,2) =  3.0;
    mtrx_2(1,0) =  4.0;
    mtrx_2(1,1) =  5.0;
    mtrx_2(1,2) =  6.0;
    mtrx_2(2,0) =  7.0;
    mtrx_2(2,1) =  8.0;
    mtrx_2(2,2) =  9.0;

    mtrx_1 += mtrx_2;

    QVERIFY( fabs( mtrx_1(0,0) -  2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) -  4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) -  6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,0) -  8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 10.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 12.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,0) - 14.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 16.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 18.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorUnarySubstraction()
{
    MSc_Matrix3x3 mtrx_1;
    MSc_Matrix3x3 mtrx_2;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_2(0,0) =  1.0;
    mtrx_2(0,1) =  2.0;
    mtrx_2(0,2) =  3.0;
    mtrx_2(1,0) =  4.0;
    mtrx_2(1,1) =  5.0;
    mtrx_2(1,2) =  6.0;
    mtrx_2(2,0) =  7.0;
    mtrx_2(2,1) =  8.0;
    mtrx_2(2,2) =  9.0;

    mtrx_1 -= mtrx_2;

    QVERIFY( fabs( mtrx_1(0,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,0) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorUnaryMultiplication()
{
    MSc_Matrix3x3 mtrx_1;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_1 *= 2.0;

    QVERIFY( fabs( mtrx_1(0,0) -  2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) -  4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) -  6.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,0) -  8.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 10.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 12.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,0) - 14.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 16.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 18.0 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

void MSc_Matrix3x3Test::testOperatorUnaryDivision()
{
    MSc_Matrix3x3 mtrx_1;

    mtrx_1(0,0) =  1.0;
    mtrx_1(0,1) =  2.0;
    mtrx_1(0,2) =  3.0;
    mtrx_1(1,0) =  4.0;
    mtrx_1(1,1) =  5.0;
    mtrx_1(1,2) =  6.0;
    mtrx_1(2,0) =  7.0;
    mtrx_1(2,1) =  8.0;
    mtrx_1(2,2) =  9.0;

    mtrx_1 /= 2.0;

    QVERIFY( fabs( mtrx_1(0,0) - 0.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,1) - 1.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(0,2) - 1.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,0) - 2.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,1) - 2.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(1,2) - 3.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,0) - 3.5 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,1) - 4.0 ) < 10.0e-9 );
    QVERIFY( fabs( mtrx_1(2,2) - 4.5 ) < 10.0e-9 );
}

////////////////////////////////////////////////////////////////////////////////

QTEST_APPLESS_MAIN(MSc_Matrix3x3Test)

////////////////////////////////////////////////////////////////////////////////

#include "tst_msc_matrix3x3test.moc"
